﻿using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Net;
using System.Text;

namespace HttpCrawler.Engine
{
    public class HttpCrawlerContent : IDisposable
    {
        private static readonly ReadOnlyCollection<string> _HtmlMimeTypes = new ReadOnlyCollection<string>(new[] 
        { 
            "application/xhtml+xml", 
            "text/html",
        });

        public static ReadOnlyCollection<string> HtmlMimeTypes
        {
            get
            {
                return _HtmlMimeTypes;
            }
        }

        private static ReadOnlyCollection<string> _XmlMimeTypes = new ReadOnlyCollection<string>(new[]
        { 
            "text/xml" 
        });

        public static ReadOnlyCollection<string> XmlMimeTypes
        {
            get
            {
                return _XmlMimeTypes;
            }
        }

        private static ReadOnlyCollection<string> _CssMimeTypes = new ReadOnlyCollection<string>(new[]
        {
            "text/css"
        });

        public static ReadOnlyCollection<string> CssMimeTypes
        {
            get
            {
                return _CssMimeTypes;
            }
        }

        public HttpCrawlerContent(Uri requestUrl, Uri referrerUrl, HttpWebResponse webResponse)
        {
            if (requestUrl == null)
            {
                throw new ArgumentNullException("requestUrl");
            }

            if (webResponse == null)
            {
                throw new ArgumentNullException("webResponse");
            }

            RequestUrl = requestUrl;
            ReferrerUrl = referrerUrl;
            ResponseUrl = webResponse.ResponseUri;
            MimeType = webResponse.GetMimeType();

            using (var stream = webResponse.GetResponseStream())
            {
                stream.CopyTo(_Stream);
            }

            _Stream.Position = 0;
        }

        public Uri ReferrerUrl
        {
            get;
            protected set;
        }

        public Uri RequestUrl
        {
            get;
            protected set;
        }

        public Uri ResponseUrl
        {
            get;
            protected set;
        }

        public string MimeType
        {
            get;
            protected set;
        }

        public static bool IsHtml(string mimeType)
        {
            return HtmlMimeTypes.Contains(mimeType);
        }

        public static bool IsXml(string mimeType)
        {
            return XmlMimeTypes.Contains(mimeType);
        }

        public static bool IsCss(string mimeType)
        {
            return CssMimeTypes.Contains(mimeType);
        }

        public bool IsHtml()
        {
            return IsHtml(MimeType);
        }

        public bool IsXml()
        {
            return IsXml(MimeType);
        }

        public bool IsCss()
        {
            return IsCss(MimeType);
        }

        private readonly MemoryStream _Stream = new MemoryStream();

        protected MemoryStream Stream
        {
            get
            {
                return _Stream;
            }
        }

        public virtual void Save(Stream stream)
        {
            _Stream.Position = 0;
            _Stream.CopyTo(stream);
        }

        public virtual long Size
        {
            get
            {
                return _Stream.Length;
            }
        }

        public virtual string Text
        {
            get
            {
                return Encoding.UTF8.GetString(_Stream.ToArray());
            }
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                _Stream.Dispose();
            }
        }

        public void Dispose()
        {
            Dispose(true);

            GC.SuppressFinalize(this);
        }
    }
}
